Name: Huiying Ba, He Chen, Zhaoying Chen, Tenisa Lee, Yiying Wang, Qifan Yang

From this research, we want to find out what factors affect people’s happiness, do these factors vary between different countries, and which country’s people live the happiest.

Explore Dataset

paste("Number of rows:", nrow(Happiness))
[1] "Number of rows: 155"
paste("Number of columns:",ncol(Happiness))
[1] "Number of columns: 12"
paste("Name of columns:", colnames(Happiness))
 [1] "Name of columns: country"              "Name of columns: region"              
 [3] "Name of columns: year"                 "Name of columns: rank"                
 [5] "Name of columns: score"                "Name of columns: gdp"                 
 [7] "Name of columns: family"               "Name of columns: health"              
 [9] "Name of columns: freedom"              "Name of columns: trust_gov_corruption"
[11] "Name of columns: generosity"           "Name of columns: dystopia_residual"   

Number 1: Histogram of World Happiness Score

h <- hist(Happiness$score,
          main = "Histogram of World Happiness Score",
          xlab = "Happiness Score",
          xlim = c(2,9),
          ylim = c(0,35),
          col = "pink"
)
text(h$mids,h$counts,labels = h$counts, adj = c(0.5,-0.5))

The histogram output of world happiness score shows that the result is normally distributed, the peak in this histogram lies between the happiness score of 5 and 5.5. This peak indicates that the majority of the countries, 30 countries out of 155, have an average happiness score between 5 and 5.5. Three countries have the highest happiness score which is between 7.5 and 8, these three happiest countries are Norway, Denmark, and Iceland.

Number 2: Happiness Score in Different Regions

ggplot(Happiness_1, aes(x = region, y = score, color = region)) +
  geom_boxplot()+
  labs(title ="Happiness Score in Different Regions",x= "Region", y = "Happiness Score")+
  theme(axis.text.x=element_blank())+
  geom_hline(yintercept = 5.4, color="black", size=1.3, linetype="dashed")+
  geom_text(aes(0,5.4,label = "Average", vjust = -1, hjust=0, size = 8))

Given the world happiness score histogram above, we concluded that the average happiness score is 5.4. Regions with all countries above the average happiness scores are Australia and New Zealand, North America and Western Europe, which indicates that people from all countries in these three regions are living happily. The majority of the countries in regions such as Eastern Asia, Latin America and Carribean, and Southern Asia also have a high average happiness score.

Number 3: Region VS World Happiness Score

Happy_1<-Happiness %>%
  group_by(region) %>%
  summarize(
    Happy_avg=mean(score))
Happy_1<-Happy_1[-11,]
ggplot(data = Happy_1,aes(x=reorder(region,Happy_avg), y = Happy_avg))+
  geom_col(aes(fill=region),show.legend = FALSE)+
  labs(title = "Region VS World Happiness Score", x = "Region", y = "Average Happiness Score")+
  theme(legend.title = element_blank())+
  coord_flip()

Compared to the other regions, Australia and New Zealand is heavenliness and North America is followed by. The scores of both regions are over 7. And Sub-Saharan Africa is the least happiness region and the score is 4.139667.

Number 4: Top 10 Happiest Countries

Happy_country <-head(Happiness,10) %>%
  select(region, country, rank, score, gdp)
Happy_country
 ggplot(Happy_country,aes(x=country,y=score,fill=region))+
   geom_col(aes(x=reorder(country,score), y =score))+
   theme_classic() +
   theme(axis.text.x = element_text(vjust=0.6))+
  labs(title = "Top 10 Happiest Countries", y="Happiness Score")+
  coord_flip()

Among the top 10 happiest countries, 7 out of the 10 countries are from Western Europe and the other two are from Australia and New Zealand and the last one in North America. Their happiness scores are quite similar, between 7.2 to 7.4, and their GDP is over 1.4. Since there are only two countries in Australia and New Zealand, the region of Australia and New Zealand ranks first among all other regions. Though the top 7 happiest countries are from western Europe, the happiness score of Italy, North Cyprus, Greece, and Portugal are below 6. Therefore, the average score of Western Europe is relatively lower.

Number 5: Correlogram of World Happiness Score

# Correlation matrix
data2017Var<-Happiness[,c("score",
                         "gdp",
                         "family",
                         "health",
                         "freedom",
                         "trust_gov_corruption","generosity","dystopia_residual")]
corr <- round(cor(data2017Var), 2)

# Plot
ggcorrplot(corr, hc.order = TRUE, 
           #type = "lower", 
           lab = TRUE, 
           lab_size = 3, 
           method="circle", 
           colors = c("tomato2", "white", "springgreen3"), 
           title="Correlogram of World Happiness Score ", 
           ggtheme=theme_bw)

From the chart above, we can see that GDP and health have the highest correlation with happiness scores. Family is the third strongest correlation among the rest variables. Freedom and dystopia_residual have less effect on happiness scores. Trust of government bearly has any influence on happiness score.

Number 6: GDP vs. World Happiness Score

ggplot(Happiness, aes(x = gdp, y = score)) +
  geom_point(aes(color="#fddde6"),alpha=0.5,show.legend = F) +
  geom_smooth(method = lm,color="#696969")+
  labs(title = "GDP vs. World Happiness Score",
       x = "GDP", y = "Happiness Score")

From the linear model above, we can see a positive relationship between GDP and happiness scores. By comparing the 95% confidence interval from the regression line, GDP has the smallest grey zone, revealing that the regression line between GDP and happiness score is the most accurate. Since the correlation coefficient between GDP and happiness score is the highest, which is 0.84, GDP has the most effect on the happiness score.

Number 7: Health vs. World Happiness Score

ggplot(Happiness, aes(x = health, y = score)) +
  geom_point(aes(color="#fddde6"),alpha=0.5,show.legend = F) +
  geom_smooth(method = lm,color="#696969")+
  labs(title = "Health vs. World Happiness Score",
       x = "Health", y = "Happiness Score")

According to the previous plot, happiness is proportional to health. People who live in a healthy life are more happy than who are not. Health score is distributed in 0 to 1.0 and mostly countries are among 0.6-0.9. For countries whose happiness scores are over 7, their health scores are all above 0.75. When the health score is under 0.5, no country has a happiness score over 6.In addition, the correlation of health and happiness is 0.8 is quite strong. So health is really an important factor which affects happiness score.

Number 8: Family vs. World Happiness Score

ggplot(Happiness, aes(x = family, y = score)) +
  geom_point(aes(color="#fddde6"),alpha=0.5,show.legend = F) +
  geom_smooth(method = lm,color="#696969")+
  labs(title = "Family vs. World Happiness Score",
       x = "Family", y = "Happiness Score")

From the chart above, we can see that family positively contributes to the calculation of the happiness score, in other words, they are positively correlated. The closer the family bonds, the higher the happiness score of that country. However, even though the correlation between family and happiness score is relatively less strong than GDP and health, the dots plotted in this chart are more concentrated, meaning that most of the families are happy with high happiness scores no matter where they live in.

Number 9: GDP vs. Happiness Score in Each Region

ggplot(Happiness_1, aes(x = gdp, y = score, color = region)) +
  geom_point(alpha = 0.2, position = "jitter") +
  facet_wrap(~region) +
  geom_smooth(method = "lm", se = FALSE)+
  labs(title = "GDP vs. Happiness Score in Each Region",x="GDP",y="Happiness Score")

Using the facet_wrap, we can have a collective view of each region’s GDP and its relationship with the happiness score. The result shows that most of the regions have positive relationships between GDP and happiness scores. We also noticed that Western Europe has the strongest relationship. Although Australia and New Zealand and North America do not reflect positive linear relationships, the countries still have high GDP with high happiness scores. Thus, we can conclude that Australia and New Zealand, North America and Western Europe are the best regions to live based on the highest GDP. On the other side, Sub-Saharan Africa has the weakest positive relationship between GDP and happiness scores with low GDP and low happiness scores in all countries. Thus, Sub-Saharan Africa is the most unhappy region and is inhospitable to live. Using the same code, we got the same results for health and family.

Number 10: GDP vs. Health vs. Happiness Score

Size = Score, Color = Region

h <- as.data.frame(Happiness)
h %>% filter(!is.na(region)) -> h1
p <- h1 %>% 
  mutate(text = paste("Country: ", country, "\nGDP: ", gdp, "\nScore: ", score, "\nHealth: ", health, sep="")) %>%
ggplot(aes(x=gdp, y=health, size=score,color=region, text=text))+
  geom_point(alpha = 0.6, na.rm = T) +
  scale_size(range = c(0.01, 7), name="Region") +
  scale_color_viridis(discrete=TRUE, guide=FALSE) +
  theme_ipsum() +
  labs(title = "GDP vs. Health vs. Happiness Score", x="GDP",y="Health")
ggplotly(p, tooltip="text")

According to the correlogram of happiness, GDP and health are strongly and positively correlated. When choosing GDP and health as independent variables and happiness score as dependent variable, the correlation coefficient raises to 0.83, compared with the values between single variable and happiness scores. Thus, if a country has a high GDP and a high health score, it is more likely to have a high happiness score. The happiest regions reflected from this chart are still Australia and New Zealand, North America and Western Europe.

Number 11: GDP vs. Family vs. Happiness Score

Size = Score, Color = Region

h <- as.data.frame(Happiness)
h %>% filter(!is.na(region)) -> h1
p <- h1 %>% 
  mutate(text = paste("Country: ", country, "\nGDP: ", gdp, "\nScore: ", score, "\nFamily: ", family, sep="")) %>%
ggplot(aes(x=gdp, y=family, size=score,color=region, text=text))+
  geom_point(alpha = 0.6, na.rm = T) +
  scale_size(range = c(0.01, 7), name="Region") +
  scale_color_viridis(discrete=TRUE, guide=FALSE) +
  theme_ipsum() +
  labs(title = "GDP vs. Family vs. Happiness Score", x="GDP",y="Family")
ggplotly(p, tooltip="text")

According to the correlogram of happiness, GDP and family are moderately and positively correlated. When choosing GDP and family as independent variables and happiness score as dependent variable, the correlation coefficient raises to 0.86, compared with the values between single variable and happiness scores. Thus, if a country has a high GDP and a high family score, it is more likely to have a high happiness score. The happiest regions reflected from this chart are still Australia and New Zealand, North America and Western Europe.

Number 12: Family vs. Health vs. Happiness Score

Size = Score, Color = Region

h <- as.data.frame(Happiness)
h %>% filter(!is.na(region)) -> h1
p <- h1 %>% 
  mutate(text = paste("Country: ", country, "\nFamily: ", family, "\nScore: ", score, "\nHealth: ", health, sep="")) %>%
ggplot(aes(x=health, y=family, size=score,color=region, text=text))+
  geom_point(alpha = 0.6, na.rm = T) +
  scale_size(range = c(0.01, 7), name="Region") +
  scale_color_viridis(discrete=TRUE, guide=FALSE) +
  theme_ipsum() +
  labs(title = "Health vs. Family vs. Happiness Score", x="Health",y="Family") 
 
ggplotly(p, tooltip="text")

According to the correlogram of happiness, health and family are moderately and positively correlated. When choosing health and family as independent variables and happiness score as dependent variable, the correlation coefficient raises to 0.86, compared with the values between single variable and happiness scores. Thus, if a country has a high health score and a high family score, it is more likely to have a high happiness score. The happiest regions reflected from this chart are still Australia and New Zealand, North America and Western Europe.

LS0tCnRpdGxlOiAiVGVhbTMgQXNzaWdubWVudCAtIFdvcmxkIEhhcHBpbmVzcyBSZXBvcnQiCnN1YnRpdGxlOiAiQkE3ODAgLSBGYWxsIDIwMTkiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KKipOYW1lOioqIEh1aXlpbmcgQmEsIEhlIENoZW4sIFpoYW95aW5nIENoZW4sIFRlbmlzYSBMZWUsIFlpeWluZyBXYW5nLCBRaWZhbiBZYW5nCgojIyMjIyBGcm9tIHRoaXMgcmVzZWFyY2gsIHdlIHdhbnQgdG8gZmluZCBvdXQgd2hhdCBmYWN0b3JzIGFmZmVjdCBwZW9wbGUncyBoYXBwaW5lc3MsIGRvIHRoZXNlIGZhY3RvcnMgdmFyeSBiZXR3ZWVuIGRpZmZlcmVudCBjb3VudHJpZXMsIGFuZCB3aGljaCBjb3VudHJ5J3MgcGVvcGxlIGxpdmUgdGhlIGhhcHBpZXN0LgoKCmBgYHtyIGluY2x1ZGU9RkFMU0V9Cmluc3RhbGwucGFja2FnZXMoYygidGlkeXZlcnNlIiwgIm9wZW54bHN4IiwgImdndGhlbWVzIiwgImdnY29ycnBsb3QiLCAicGxvdGx5IiwgIm1hcHMiLCAidmlyaWRpcyIsICJocmJydGhlbWVzIikpCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGdnY29ycnBsb3QpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkoaHJicnRoZW1lcykKSGFwcGluZXNzIDwtIHJlYWRfY3N2KCIyMDE3IC0gMjAxNy5jc3YiKQpIYXBwaW5lc3NfMSA8LUhhcHBpbmVzc1stMTU1LF0KSGFwcGluZXNzXzEgPC1IYXBwaW5lc3NfMVstMTM5LF0KSGFwcGluZXNzXzEgPC1IYXBwaW5lc3NfMVstMTEzLF0KYGBgIAoKIyMjIEV4cGxvcmUgRGF0YXNldApgYGB7cn0KcGFzdGUoIk51bWJlciBvZiByb3dzOiIsIG5yb3coSGFwcGluZXNzKSkKcGFzdGUoIk51bWJlciBvZiBjb2x1bW5zOiIsbmNvbChIYXBwaW5lc3MpKQpwYXN0ZSgiTmFtZSBvZiBjb2x1bW5zOiIsIGNvbG5hbWVzKEhhcHBpbmVzcykpCgpgYGAKCiMjIyBOdW1iZXIgMTogSGlzdG9ncmFtIG9mIFdvcmxkIEhhcHBpbmVzcyBTY29yZQpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9CmggPC0gaGlzdChIYXBwaW5lc3Mkc2NvcmUsCiAgICAgICAgICBtYWluID0gIkhpc3RvZ3JhbSBvZiBXb3JsZCBIYXBwaW5lc3MgU2NvcmUiLAogICAgICAgICAgeGxhYiA9ICJIYXBwaW5lc3MgU2NvcmUiLAogICAgICAgICAgeGxpbSA9IGMoMiw5KSwKICAgICAgICAgIHlsaW0gPSBjKDAsMzUpLAogICAgICAgICAgY29sID0gInBpbmsiCikKdGV4dChoJG1pZHMsaCRjb3VudHMsbGFiZWxzID0gaCRjb3VudHMsIGFkaiA9IGMoMC41LC0wLjUpKQpgYGAKClRoZSBoaXN0b2dyYW0gb3V0cHV0IG9mIHdvcmxkIGhhcHBpbmVzcyBzY29yZSBzaG93cyB0aGF0IHRoZSByZXN1bHQgaXMgbm9ybWFsbHkgZGlzdHJpYnV0ZWQsIHRoZSBwZWFrIGluIHRoaXMgaGlzdG9ncmFtIGxpZXMgYmV0d2VlbiB0aGUgaGFwcGluZXNzIHNjb3JlIG9mIDUgYW5kIDUuNS4gVGhpcyBwZWFrIGluZGljYXRlcyB0aGF0IHRoZSBtYWpvcml0eSBvZiB0aGUgY291bnRyaWVzLCAzMCBjb3VudHJpZXMgb3V0IG9mIDE1NSwgaGF2ZSBhbiBhdmVyYWdlIGhhcHBpbmVzcyBzY29yZSBiZXR3ZWVuIDUgYW5kIDUuNS4gVGhyZWUgY291bnRyaWVzIGhhdmUgdGhlIGhpZ2hlc3QgaGFwcGluZXNzIHNjb3JlIHdoaWNoIGlzIGJldHdlZW4gNy41IGFuZCA4LCB0aGVzZSB0aHJlZSBoYXBwaWVzdCBjb3VudHJpZXMgYXJlIE5vcndheSwgRGVubWFyaywgYW5kIEljZWxhbmQuIAoKCiMjIyBOdW1iZXIgMjogSGFwcGluZXNzIFNjb3JlIGluIERpZmZlcmVudCBSZWdpb25zCgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9CmdncGxvdChIYXBwaW5lc3NfMSwgYWVzKHggPSByZWdpb24sIHkgPSBzY29yZSwgY29sb3IgPSByZWdpb24pKSArCiAgZ2VvbV9ib3hwbG90KCkrCiAgbGFicyh0aXRsZSA9IkhhcHBpbmVzcyBTY29yZSBpbiBEaWZmZXJlbnQgUmVnaW9ucyIseD0gIlJlZ2lvbiIsIHkgPSAiSGFwcGluZXNzIFNjb3JlIikrCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF9ibGFuaygpKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LjQsIGNvbG9yPSJibGFjayIsIHNpemU9MS4zLCBsaW5ldHlwZT0iZGFzaGVkIikrCiAgZ2VvbV90ZXh0KGFlcygwLDUuNCxsYWJlbCA9ICJBdmVyYWdlIiwgdmp1c3QgPSAtMSwgaGp1c3Q9MCwgc2l6ZSA9IDgpKQoKYGBgCkdpdmVuIHRoZSB3b3JsZCBoYXBwaW5lc3Mgc2NvcmUgaGlzdG9ncmFtIGFib3ZlLCB3ZSBjb25jbHVkZWQgdGhhdCB0aGUgYXZlcmFnZSBoYXBwaW5lc3Mgc2NvcmUgaXMgNS40LiBSZWdpb25zIHdpdGggYWxsIGNvdW50cmllcyBhYm92ZSB0aGUgYXZlcmFnZSBoYXBwaW5lc3Mgc2NvcmVzIGFyZSBBdXN0cmFsaWEgYW5kIE5ldyBaZWFsYW5kLCBOb3J0aCBBbWVyaWNhIGFuZCBXZXN0ZXJuIEV1cm9wZSwgd2hpY2ggaW5kaWNhdGVzIHRoYXQgcGVvcGxlIGZyb20gYWxsIGNvdW50cmllcyBpbiB0aGVzZSB0aHJlZSByZWdpb25zIGFyZSBsaXZpbmcgaGFwcGlseS4gVGhlIG1ham9yaXR5IG9mIHRoZSBjb3VudHJpZXMgaW4gcmVnaW9ucyBzdWNoIGFzIEVhc3Rlcm4gQXNpYSwgTGF0aW4gQW1lcmljYSBhbmQgQ2FycmliZWFuLCBhbmQgU291dGhlcm4gQXNpYSBhbHNvIGhhdmUgYSBoaWdoIGF2ZXJhZ2UgaGFwcGluZXNzIHNjb3JlLgoKIyMjIE51bWJlciAzOiBSZWdpb24gVlMgV29ybGQgSGFwcGluZXNzIFNjb3JlCgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9CkhhcHB5XzE8LUhhcHBpbmVzcyAlPiUKICBncm91cF9ieShyZWdpb24pICU+JQogIHN1bW1hcml6ZSgKICAgIEhhcHB5X2F2Zz1tZWFuKHNjb3JlKSkKSGFwcHlfMTwtSGFwcHlfMVstMTEsXQpnZ3Bsb3QoZGF0YSA9IEhhcHB5XzEsYWVzKHg9cmVvcmRlcihyZWdpb24sSGFwcHlfYXZnKSwgeSA9IEhhcHB5X2F2ZykpKwogIGdlb21fY29sKGFlcyhmaWxsPXJlZ2lvbiksc2hvdy5sZWdlbmQgPSBGQUxTRSkrCiAgbGFicyh0aXRsZSA9ICJSZWdpb24gVlMgV29ybGQgSGFwcGluZXNzIFNjb3JlIiwgeCA9ICJSZWdpb24iLCB5ID0gIkF2ZXJhZ2UgSGFwcGluZXNzIFNjb3JlIikrCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSsKICBjb29yZF9mbGlwKCkKYGBgCkNvbXBhcmVkIHRvIHRoZSBvdGhlciByZWdpb25zLCBBdXN0cmFsaWEgYW5kIE5ldyBaZWFsYW5kICBpcyBoZWF2ZW5saW5lc3MgYW5kIE5vcnRoIEFtZXJpY2EgaXMgZm9sbG93ZWQgYnkuIFRoZSBzY29yZXMgb2YgYm90aCByZWdpb25zIGFyZSBvdmVyIDcuIEFuZCBTdWItU2FoYXJhbiBBZnJpY2EgaXMgdGhlIGxlYXN0IGhhcHBpbmVzcyByZWdpb24gYW5kIHRoZSBzY29yZSBpcyA0LjEzOTY2Ny4gCgojIyMgTnVtYmVyIDQ6IFRvcCAxMCBIYXBwaWVzdCBDb3VudHJpZXMKCmBgYHtyLGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9Nn0KSGFwcHlfY291bnRyeSA8LWhlYWQoSGFwcGluZXNzLDEwKSAlPiUKICBzZWxlY3QocmVnaW9uLCBjb3VudHJ5LCByYW5rLCBzY29yZSwgZ2RwKQpIYXBweV9jb3VudHJ5CmBgYAoKYGBge3IsZmlnLndpZHRoPTgsZmlnLmhlaWdodD02fQogZ2dwbG90KEhhcHB5X2NvdW50cnksYWVzKHg9Y291bnRyeSx5PXNjb3JlLGZpbGw9cmVnaW9uKSkrCiAgIGdlb21fY29sKGFlcyh4PXJlb3JkZXIoY291bnRyeSxzY29yZSksIHkgPXNjb3JlKSkrCiAgIHRoZW1lX2NsYXNzaWMoKSArCiAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHZqdXN0PTAuNikpKwogIGxhYnModGl0bGUgPSAiVG9wIDEwIEhhcHBpZXN0IENvdW50cmllcyIsIHk9IkhhcHBpbmVzcyBTY29yZSIpKwogIGNvb3JkX2ZsaXAoKQoKYGBgCkFtb25nIHRoZSB0b3AgMTAgaGFwcGllc3QgY291bnRyaWVzLCA3IG91dCBvZiB0aGUgMTAgY291bnRyaWVzIGFyZSBmcm9tIFdlc3Rlcm4gRXVyb3BlIGFuZCB0aGUgb3RoZXIgdHdvIGFyZSBmcm9tIEF1c3RyYWxpYSBhbmQgTmV3IFplYWxhbmQgYW5kIHRoZSBsYXN0IG9uZSBpbiBOb3J0aCBBbWVyaWNhLiBUaGVpciBoYXBwaW5lc3Mgc2NvcmVzIGFyZSBxdWl0ZSBzaW1pbGFyLCBiZXR3ZWVuIDcuMiB0byA3LjQsIGFuZCB0aGVpciBHRFAgaXMgb3ZlciAxLjQuIFNpbmNlIHRoZXJlIGFyZSBvbmx5IHR3byBjb3VudHJpZXMgaW4gQXVzdHJhbGlhIGFuZCBOZXcgWmVhbGFuZCwgdGhlIHJlZ2lvbiBvZiBBdXN0cmFsaWEgYW5kIE5ldyBaZWFsYW5kIHJhbmtzIGZpcnN0IGFtb25nIGFsbCBvdGhlciByZWdpb25zLiBUaG91Z2ggdGhlIHRvcCA3IGhhcHBpZXN0IGNvdW50cmllcyBhcmUgZnJvbSB3ZXN0ZXJuIEV1cm9wZSwgdGhlIGhhcHBpbmVzcyBzY29yZSBvZiBJdGFseSwgTm9ydGggQ3lwcnVzLCBHcmVlY2UsIGFuZCBQb3J0dWdhbCBhcmUgYmVsb3cgNi4gVGhlcmVmb3JlLCB0aGUgYXZlcmFnZSBzY29yZSBvZiBXZXN0ZXJuIEV1cm9wZSBpcyByZWxhdGl2ZWx5IGxvd2VyLgoKCiMjIyBOdW1iZXIgNTogQ29ycmVsb2dyYW0gb2YgV29ybGQgSGFwcGluZXNzIFNjb3JlIAoKYGBge3IsZmlnLndpZHRoPTgsZmlnLmhlaWdodD02fQojIENvcnJlbGF0aW9uIG1hdHJpeApkYXRhMjAxN1ZhcjwtSGFwcGluZXNzWyxjKCJzY29yZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAiZ2RwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICJmYW1pbHkiLAogICAgICAgICAgICAgICAgICAgICAgICAgImhlYWx0aCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAiZnJlZWRvbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAidHJ1c3RfZ292X2NvcnJ1cHRpb24iLCJnZW5lcm9zaXR5IiwiZHlzdG9waWFfcmVzaWR1YWwiKV0KY29yciA8LSByb3VuZChjb3IoZGF0YTIwMTdWYXIpLCAyKQoKIyBQbG90CmdnY29ycnBsb3QoY29yciwgaGMub3JkZXIgPSBUUlVFLCAKICAgICAgICAgICAjdHlwZSA9ICJsb3dlciIsIAogICAgICAgICAgIGxhYiA9IFRSVUUsIAogICAgICAgICAgIGxhYl9zaXplID0gMywgCiAgICAgICAgICAgbWV0aG9kPSJjaXJjbGUiLCAKICAgICAgICAgICBjb2xvcnMgPSBjKCJ0b21hdG8yIiwgIndoaXRlIiwgInNwcmluZ2dyZWVuMyIpLCAKICAgICAgICAgICB0aXRsZT0iQ29ycmVsb2dyYW0gb2YgV29ybGQgSGFwcGluZXNzIFNjb3JlICIsIAogICAgICAgICAgIGdndGhlbWU9dGhlbWVfYncpCgpgYGAKRnJvbSB0aGUgY2hhcnQgYWJvdmUsIHdlIGNhbiBzZWUgdGhhdCBHRFAgYW5kIGhlYWx0aCBoYXZlIHRoZSBoaWdoZXN0IGNvcnJlbGF0aW9uIHdpdGggaGFwcGluZXNzIHNjb3Jlcy4gIEZhbWlseSBpcyB0aGUgdGhpcmQgc3Ryb25nZXN0IGNvcnJlbGF0aW9uIGFtb25nIHRoZSByZXN0IHZhcmlhYmxlcy4gRnJlZWRvbSBhbmQgZHlzdG9waWFfcmVzaWR1YWwgaGF2ZSBsZXNzIGVmZmVjdCBvbiBoYXBwaW5lc3Mgc2NvcmVzLiBUcnVzdCBvZiBnb3Zlcm5tZW50IGJlYXJseSBoYXMgYW55IGluZmx1ZW5jZSBvbiBoYXBwaW5lc3Mgc2NvcmUuCgoKIyMjIE51bWJlciA2OiBHRFAgdnMuIFdvcmxkIEhhcHBpbmVzcyBTY29yZSAKYGBge3IsZmlnLndpZHRoPTgsZmlnLmhlaWdodD02fQpnZ3Bsb3QoSGFwcGluZXNzLCBhZXMoeCA9IGdkcCwgeSA9IHNjb3JlKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG9yPSIjZmRkZGU2IiksYWxwaGE9MC41LHNob3cubGVnZW5kID0gRikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9IGxtLGNvbG9yPSIjNjk2OTY5IikrCiAgbGFicyh0aXRsZSA9ICJHRFAgdnMuIFdvcmxkIEhhcHBpbmVzcyBTY29yZSIsCiAgICAgICB4ID0gIkdEUCIsIHkgPSAiSGFwcGluZXNzIFNjb3JlIikKYGBgCgpGcm9tIHRoZSBsaW5lYXIgbW9kZWwgYWJvdmUsIHdlIGNhbiBzZWUgYSBwb3NpdGl2ZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBHRFAgYW5kIGhhcHBpbmVzcyBzY29yZXMuIEJ5IGNvbXBhcmluZyB0aGUgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgZnJvbSB0aGUgcmVncmVzc2lvbiBsaW5lLCBHRFAgaGFzIHRoZSBzbWFsbGVzdCBncmV5IHpvbmUsIHJldmVhbGluZyB0aGF0IHRoZSByZWdyZXNzaW9uIGxpbmUgYmV0d2VlbiBHRFAgYW5kIGhhcHBpbmVzcyBzY29yZSBpcyB0aGUgbW9zdCBhY2N1cmF0ZS4gU2luY2UgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IGJldHdlZW4gR0RQIGFuZCBoYXBwaW5lc3Mgc2NvcmUgaXMgdGhlIGhpZ2hlc3QsIHdoaWNoIGlzIDAuODQsIEdEUCBoYXMgdGhlIG1vc3QgZWZmZWN0IG9uIHRoZSBoYXBwaW5lc3Mgc2NvcmUuCgojIyMgTnVtYmVyIDc6IEhlYWx0aCB2cy4gV29ybGQgSGFwcGluZXNzIFNjb3JlCmBgYHtyLGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9Nn0KZ2dwbG90KEhhcHBpbmVzcywgYWVzKHggPSBoZWFsdGgsIHkgPSBzY29yZSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj0iI2ZkZGRlNiIpLGFscGhhPTAuNSxzaG93LmxlZ2VuZCA9IEYpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSxjb2xvcj0iIzY5Njk2OSIpKwogIGxhYnModGl0bGUgPSAiSGVhbHRoIHZzLiBXb3JsZCBIYXBwaW5lc3MgU2NvcmUiLAogICAgICAgeCA9ICJIZWFsdGgiLCB5ID0gIkhhcHBpbmVzcyBTY29yZSIpCmBgYApBY2NvcmRpbmcgdG8gdGhlIHByZXZpb3VzIHBsb3QsIGhhcHBpbmVzcyBpcyBwcm9wb3J0aW9uYWwgdG8gaGVhbHRoLiBQZW9wbGUgd2hvIGxpdmUgaW4gYSBoZWFsdGh5IGxpZmUgYXJlIG1vcmUgaGFwcHkgdGhhbiB3aG8gYXJlIG5vdC4gSGVhbHRoIHNjb3JlIGlzIGRpc3RyaWJ1dGVkIGluIDAgdG8gMS4wIGFuZCBtb3N0bHkgY291bnRyaWVzIGFyZSBhbW9uZyAwLjYtMC45LiBGb3IgY291bnRyaWVzIHdob3NlIGhhcHBpbmVzcyBzY29yZXMgYXJlIG92ZXIgNywgdGhlaXIgaGVhbHRoIHNjb3JlcyBhcmUgYWxsIGFib3ZlIDAuNzUuIFdoZW4gdGhlIGhlYWx0aCBzY29yZSBpcyB1bmRlciAwLjUsIG5vIGNvdW50cnkgaGFzIGEgaGFwcGluZXNzIHNjb3JlIG92ZXIgNi5JbiBhZGRpdGlvbiwgdGhlIGNvcnJlbGF0aW9uIG9mIGhlYWx0aCBhbmQgaGFwcGluZXNzIGlzIDAuOCBpcyBxdWl0ZSBzdHJvbmcuIFNvIGhlYWx0aCBpcyByZWFsbHkgYW4gaW1wb3J0YW50IGZhY3RvciB3aGljaCBhZmZlY3RzIGhhcHBpbmVzcyBzY29yZS4gCgojIyMgTnVtYmVyIDg6IEZhbWlseSB2cy4gV29ybGQgSGFwcGluZXNzIFNjb3JlCmBgYHtyLGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9Nn0KZ2dwbG90KEhhcHBpbmVzcywgYWVzKHggPSBmYW1pbHksIHkgPSBzY29yZSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvcj0iI2ZkZGRlNiIpLGFscGhhPTAuNSxzaG93LmxlZ2VuZCA9IEYpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSBsbSxjb2xvcj0iIzY5Njk2OSIpKwogIGxhYnModGl0bGUgPSAiRmFtaWx5IHZzLiBXb3JsZCBIYXBwaW5lc3MgU2NvcmUiLAogICAgICAgeCA9ICJGYW1pbHkiLCB5ID0gIkhhcHBpbmVzcyBTY29yZSIpCmBgYApGcm9tIHRoZSBjaGFydCBhYm92ZSwgd2UgY2FuIHNlZSB0aGF0IGZhbWlseSBwb3NpdGl2ZWx5IGNvbnRyaWJ1dGVzIHRvIHRoZSBjYWxjdWxhdGlvbiBvZiB0aGUgaGFwcGluZXNzIHNjb3JlLCBpbiBvdGhlciB3b3JkcywgdGhleSBhcmUgcG9zaXRpdmVseSBjb3JyZWxhdGVkLiBUaGUgY2xvc2VyIHRoZSBmYW1pbHkgYm9uZHMsIHRoZSBoaWdoZXIgdGhlIGhhcHBpbmVzcyBzY29yZSBvZiB0aGF0IGNvdW50cnkuIEhvd2V2ZXIsIGV2ZW4gdGhvdWdoIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGZhbWlseSBhbmQgaGFwcGluZXNzIHNjb3JlIGlzIHJlbGF0aXZlbHkgbGVzcyBzdHJvbmcgdGhhbiBHRFAgYW5kIGhlYWx0aCwgdGhlIGRvdHMgcGxvdHRlZCBpbiB0aGlzIGNoYXJ0IGFyZSBtb3JlIGNvbmNlbnRyYXRlZCwgbWVhbmluZyB0aGF0IG1vc3Qgb2YgdGhlIGZhbWlsaWVzIGFyZSBoYXBweSB3aXRoIGhpZ2ggaGFwcGluZXNzIHNjb3JlcyBubyBtYXR0ZXIgd2hlcmUgdGhleSBsaXZlIGluLiAKCgojIyMgTnVtYmVyIDk6IEdEUCB2cy4gSGFwcGluZXNzIFNjb3JlIGluIEVhY2ggUmVnaW9uCgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9CmdncGxvdChIYXBwaW5lc3NfMSwgYWVzKHggPSBnZHAsIHkgPSBzY29yZSwgY29sb3IgPSByZWdpb24pKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMiwgcG9zaXRpb24gPSAiaml0dGVyIikgKwogIGZhY2V0X3dyYXAofnJlZ2lvbikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UpKwogIGxhYnModGl0bGUgPSAiR0RQIHZzLiBIYXBwaW5lc3MgU2NvcmUgaW4gRWFjaCBSZWdpb24iLHg9IkdEUCIseT0iSGFwcGluZXNzIFNjb3JlIikKYGBgClVzaW5nIHRoZSBmYWNldF93cmFwLCB3ZSBjYW4gaGF2ZSBhIGNvbGxlY3RpdmUgdmlldyBvZiBlYWNoIHJlZ2lvbuKAmXMgR0RQIGFuZCBpdHMgcmVsYXRpb25zaGlwIHdpdGggdGhlIGhhcHBpbmVzcyBzY29yZS4gVGhlIHJlc3VsdCBzaG93cyB0aGF0IG1vc3Qgb2YgdGhlIHJlZ2lvbnMgaGF2ZSBwb3NpdGl2ZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gR0RQIGFuZCBoYXBwaW5lc3Mgc2NvcmVzLiBXZSBhbHNvIG5vdGljZWQgdGhhdCBXZXN0ZXJuIEV1cm9wZSBoYXMgdGhlIHN0cm9uZ2VzdCByZWxhdGlvbnNoaXAuIEFsdGhvdWdoIEF1c3RyYWxpYSBhbmQgTmV3IFplYWxhbmQgYW5kIE5vcnRoIEFtZXJpY2EgZG8gbm90IHJlZmxlY3QgcG9zaXRpdmUgbGluZWFyIHJlbGF0aW9uc2hpcHMsIHRoZSBjb3VudHJpZXMgc3RpbGwgaGF2ZSBoaWdoIEdEUCB3aXRoIGhpZ2ggaGFwcGluZXNzIHNjb3Jlcy4gVGh1cywgd2UgY2FuIGNvbmNsdWRlIHRoYXQgQXVzdHJhbGlhIGFuZCBOZXcgWmVhbGFuZCwgTm9ydGggQW1lcmljYSBhbmQgV2VzdGVybiBFdXJvcGUgYXJlIHRoZSBiZXN0IHJlZ2lvbnMgdG8gbGl2ZSBiYXNlZCBvbiB0aGUgaGlnaGVzdCBHRFAuIE9uIHRoZSBvdGhlciBzaWRlLCBTdWItU2FoYXJhbiBBZnJpY2EgaGFzIHRoZSB3ZWFrZXN0IHBvc2l0aXZlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIEdEUCBhbmQgaGFwcGluZXNzIHNjb3JlcyB3aXRoIGxvdyBHRFAgYW5kIGxvdyBoYXBwaW5lc3Mgc2NvcmVzIGluIGFsbCBjb3VudHJpZXMuIFRodXMsIFN1Yi1TYWhhcmFuIEFmcmljYSBpcyB0aGUgbW9zdCB1bmhhcHB5IHJlZ2lvbiBhbmQgaXMgaW5ob3NwaXRhYmxlIHRvIGxpdmUuIFVzaW5nIHRoZSBzYW1lIGNvZGUsIHdlIGdvdCB0aGUgc2FtZSByZXN1bHRzIGZvciBoZWFsdGggYW5kIGZhbWlseS4KCgojIyMgTnVtYmVyIDEwOiBHRFAgdnMuIEhlYWx0aCB2cy4gSGFwcGluZXNzIFNjb3JlCiMjIyMgU2l6ZSA9IFNjb3JlLCBDb2xvciA9IFJlZ2lvbgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9CmggPC0gYXMuZGF0YS5mcmFtZShIYXBwaW5lc3MpCmggJT4lIGZpbHRlcighaXMubmEocmVnaW9uKSkgLT4gaDEKcCA8LSBoMSAlPiUgCiAgbXV0YXRlKHRleHQgPSBwYXN0ZSgiQ291bnRyeTogIiwgY291bnRyeSwgIlxuR0RQOiAiLCBnZHAsICJcblNjb3JlOiAiLCBzY29yZSwgIlxuSGVhbHRoOiAiLCBoZWFsdGgsIHNlcD0iIikpICU+JQpnZ3Bsb3QoYWVzKHg9Z2RwLCB5PWhlYWx0aCwgc2l6ZT1zY29yZSxjb2xvcj1yZWdpb24sIHRleHQ9dGV4dCkpKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYsIG5hLnJtID0gVCkgKwogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDAuMDEsIDcpLCBuYW1lPSJSZWdpb24iKSArCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1UUlVFLCBndWlkZT1GQUxTRSkgKwogIHRoZW1lX2lwc3VtKCkgKwogIGxhYnModGl0bGUgPSAiR0RQIHZzLiBIZWFsdGggdnMuIEhhcHBpbmVzcyBTY29yZSIsIHg9IkdEUCIseT0iSGVhbHRoIikKZ2dwbG90bHkocCwgdG9vbHRpcD0idGV4dCIpCmBgYApBY2NvcmRpbmcgdG8gdGhlIGNvcnJlbG9ncmFtIG9mIGhhcHBpbmVzcywgR0RQIGFuZCBoZWFsdGggYXJlIHN0cm9uZ2x5IGFuZCBwb3NpdGl2ZWx5IGNvcnJlbGF0ZWQuIFdoZW4gY2hvb3NpbmcgR0RQIGFuZCBoZWFsdGggYXMgaW5kZXBlbmRlbnQgdmFyaWFibGVzIGFuZCBoYXBwaW5lc3Mgc2NvcmUgYXMgZGVwZW5kZW50IHZhcmlhYmxlLCB0aGUgY29ycmVsYXRpb24gY29lZmZpY2llbnQgcmFpc2VzIHRvIDAuODMsIGNvbXBhcmVkIHdpdGggdGhlIHZhbHVlcyBiZXR3ZWVuIHNpbmdsZSB2YXJpYWJsZSBhbmQgaGFwcGluZXNzIHNjb3Jlcy4gVGh1cywgaWYgYSBjb3VudHJ5IGhhcyBhIGhpZ2ggR0RQIGFuZCBhIGhpZ2ggaGVhbHRoIHNjb3JlLCBpdCBpcyBtb3JlIGxpa2VseSB0byBoYXZlIGEgaGlnaCBoYXBwaW5lc3Mgc2NvcmUuIFRoZSBoYXBwaWVzdCByZWdpb25zIHJlZmxlY3RlZCBmcm9tIHRoaXMgY2hhcnQgYXJlIHN0aWxsIEF1c3RyYWxpYSBhbmQgTmV3IFplYWxhbmQsIE5vcnRoIEFtZXJpY2EgYW5kIFdlc3Rlcm4gRXVyb3BlLgoKCiMjIyBOdW1iZXIgMTE6IEdEUCB2cy4gRmFtaWx5IHZzLiBIYXBwaW5lc3MgU2NvcmUgCiMjIyMgU2l6ZSA9IFNjb3JlLCBDb2xvciA9IFJlZ2lvbgpgYGB7cixmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTZ9CmggPC0gYXMuZGF0YS5mcmFtZShIYXBwaW5lc3MpCmggJT4lIGZpbHRlcighaXMubmEocmVnaW9uKSkgLT4gaDEKcCA8LSBoMSAlPiUgCiAgbXV0YXRlKHRleHQgPSBwYXN0ZSgiQ291bnRyeTogIiwgY291bnRyeSwgIlxuR0RQOiAiLCBnZHAsICJcblNjb3JlOiAiLCBzY29yZSwgIlxuRmFtaWx5OiAiLCBmYW1pbHksIHNlcD0iIikpICU+JQpnZ3Bsb3QoYWVzKHg9Z2RwLCB5PWZhbWlseSwgc2l6ZT1zY29yZSxjb2xvcj1yZWdpb24sIHRleHQ9dGV4dCkpKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjYsIG5hLnJtID0gVCkgKwogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDAuMDEsIDcpLCBuYW1lPSJSZWdpb24iKSArCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZT1UUlVFLCBndWlkZT1GQUxTRSkgKwogIHRoZW1lX2lwc3VtKCkgKwogIGxhYnModGl0bGUgPSAiR0RQIHZzLiBGYW1pbHkgdnMuIEhhcHBpbmVzcyBTY29yZSIsIHg9IkdEUCIseT0iRmFtaWx5IikKZ2dwbG90bHkocCwgdG9vbHRpcD0idGV4dCIpCmBgYApBY2NvcmRpbmcgdG8gdGhlIGNvcnJlbG9ncmFtIG9mIGhhcHBpbmVzcywgR0RQIGFuZCBmYW1pbHkgYXJlIG1vZGVyYXRlbHkgYW5kIHBvc2l0aXZlbHkgY29ycmVsYXRlZC4gV2hlbiBjaG9vc2luZyBHRFAgYW5kIGZhbWlseSBhcyBpbmRlcGVuZGVudCB2YXJpYWJsZXMgYW5kIGhhcHBpbmVzcyBzY29yZSBhcyBkZXBlbmRlbnQgdmFyaWFibGUsIHRoZSBjb3JyZWxhdGlvbiBjb2VmZmljaWVudCByYWlzZXMgdG8gMC44NiwgY29tcGFyZWQgd2l0aCB0aGUgdmFsdWVzIGJldHdlZW4gc2luZ2xlIHZhcmlhYmxlIGFuZCBoYXBwaW5lc3Mgc2NvcmVzLiBUaHVzLCBpZiBhIGNvdW50cnkgaGFzIGEgaGlnaCBHRFAgYW5kIGEgaGlnaCBmYW1pbHkgc2NvcmUsIGl0IGlzIG1vcmUgbGlrZWx5IHRvIGhhdmUgYSBoaWdoIGhhcHBpbmVzcyBzY29yZS4gVGhlIGhhcHBpZXN0IHJlZ2lvbnMgcmVmbGVjdGVkIGZyb20gdGhpcyBjaGFydCBhcmUgc3RpbGwgQXVzdHJhbGlhIGFuZCBOZXcgWmVhbGFuZCwgTm9ydGggQW1lcmljYSBhbmQgV2VzdGVybiBFdXJvcGUuCgoKIyMjIE51bWJlciAxMjogRmFtaWx5IHZzLiBIZWFsdGggdnMuIEhhcHBpbmVzcyBTY29yZQojIyMjIFNpemUgPSBTY29yZSwgQ29sb3IgPSBSZWdpb24KYGBge3IsZmlnLndpZHRoPTgsZmlnLmhlaWdodD04fQpoIDwtIGFzLmRhdGEuZnJhbWUoSGFwcGluZXNzKQpoICU+JSBmaWx0ZXIoIWlzLm5hKHJlZ2lvbikpIC0+IGgxCnAgPC0gaDEgJT4lIAogIG11dGF0ZSh0ZXh0ID0gcGFzdGUoIkNvdW50cnk6ICIsIGNvdW50cnksICJcbkZhbWlseTogIiwgZmFtaWx5LCAiXG5TY29yZTogIiwgc2NvcmUsICJcbkhlYWx0aDogIiwgaGVhbHRoLCBzZXA9IiIpKSAlPiUKZ2dwbG90KGFlcyh4PWhlYWx0aCwgeT1mYW1pbHksIHNpemU9c2NvcmUsY29sb3I9cmVnaW9uLCB0ZXh0PXRleHQpKSsKICBnZW9tX3BvaW50KGFscGhhID0gMC42LCBuYS5ybSA9IFQpICsKICBzY2FsZV9zaXplKHJhbmdlID0gYygwLjAxLCA3KSwgbmFtZT0iUmVnaW9uIikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXMoZGlzY3JldGU9VFJVRSwgZ3VpZGU9RkFMU0UpICsKICB0aGVtZV9pcHN1bSgpICsKICBsYWJzKHRpdGxlID0gIkhlYWx0aCB2cy4gRmFtaWx5IHZzLiBIYXBwaW5lc3MgU2NvcmUiLCB4PSJIZWFsdGgiLHk9IkZhbWlseSIpIAogCmdncGxvdGx5KHAsIHRvb2x0aXA9InRleHQiKQpgYGAKCkFjY29yZGluZyB0byB0aGUgY29ycmVsb2dyYW0gb2YgaGFwcGluZXNzLCBoZWFsdGggYW5kIGZhbWlseSBhcmUgbW9kZXJhdGVseSBhbmQgcG9zaXRpdmVseSBjb3JyZWxhdGVkLiBXaGVuIGNob29zaW5nIGhlYWx0aCBhbmQgZmFtaWx5IGFzIGluZGVwZW5kZW50IHZhcmlhYmxlcyBhbmQgaGFwcGluZXNzIHNjb3JlIGFzIGRlcGVuZGVudCB2YXJpYWJsZSwgdGhlIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IHJhaXNlcyB0byAwLjg2LCBjb21wYXJlZCB3aXRoIHRoZSB2YWx1ZXMgYmV0d2VlbiBzaW5nbGUgdmFyaWFibGUgYW5kIGhhcHBpbmVzcyBzY29yZXMuIFRodXMsIGlmIGEgY291bnRyeSBoYXMgYSBoaWdoIGhlYWx0aCBzY29yZSBhbmQgYSBoaWdoIGZhbWlseSBzY29yZSwgaXQgaXMgbW9yZSBsaWtlbHkgdG8gaGF2ZSBhIGhpZ2ggaGFwcGluZXNzIHNjb3JlLiBUaGUgaGFwcGllc3QgcmVnaW9ucyByZWZsZWN0ZWQgZnJvbSB0aGlzIGNoYXJ0IGFyZSBzdGlsbCBBdXN0cmFsaWEgYW5kIE5ldyBaZWFsYW5kLCBOb3J0aCBBbWVyaWNhIGFuZCBXZXN0ZXJuIEV1cm9wZS4K